package main

import (
	"AnniversaryNoticeLite/pkg/cache"
	"AnniversaryNoticeLite/pkg/config"
	"AnniversaryNoticeLite/pkg/date"
	"AnniversaryNoticeLite/pkg/log"
	"AnniversaryNoticeLite/pkg/wechat"
	"fmt"
	"github.com/robfig/cron/v3"
	"go.uber.org/zap"
	"regexp"
	"strconv"
	"time"
)

func Notice() {
	todayDate := time.Now().Format(time.DateOnly)
	loveDate, err := date.DaysBetweenDates(todayDate, config.Configs.Anniversary.LoveDate)
	if err != nil {
		return
	}
	templateData := map[string]wechat.TemplateMessageDataItem{
		"love_day": {
			Value: strconv.Itoa(loveDate),
		},
		"date": {
			Value: todayDate,
		},
	}

	userData, err := wechat.GetUserList("")
	if err != nil {
		return
	}
	if len(userData.Data.Openid) == 0 {
		log.Logger.Error("用户列表为空，请前往测试账号后台新增用户")
		return
	}

	templateList, err := wechat.GetAllTemplate()
	if err != nil {
		log.Logger.Error("获取模版列表失败", zap.Error(err))
		return
	}
	if len(templateList) == 0 {
		log.Logger.Error("模版列表为空，请前往测试账号后台新增模版")
		return
	}

	for _, template := range templateList {
		log.Logger.Info(
			"模版",
			zap.String("code", template.Code),
			zap.String("title", template.Title),
			zap.String("content", template.OriginContent),
		)

		for _, match := range regexp.MustCompile(`{{(.*?)\.DATA}}`).FindAllStringSubmatch(template.OriginContent, -1) {
			if match[1] != "love_day" && match[1] != "date" {
				log.Logger.Error("模版变量错误", zap.String("变量", match[1]))
				return
			}
		}

		for _, userOpenId := range userData.Data.Openid {
			if err := wechat.SendTemplateMessage(userOpenId, template.Code, templateData); err != nil {
				log.Logger.Error(
					"发送模版消息失败",
					zap.Error(err),
					zap.String("touser", userOpenId),
					zap.String("code", template.Code),
					zap.Any("data", templateData),
				)
			}
		}
	}
}

func main() {
	config.InitConfig()
	log.InitLogger()
	cache.InitCache()

	c := cron.New(cron.WithSeconds())

	log.Logger.Info(
		"推送配置",
		zap.String("纪念日期", config.Configs.Anniversary.LoveDate),
		zap.String("推送时间", fmt.Sprintf("%d:%d", config.Configs.Notice.Hour, config.Configs.Notice.Minute)),
	)

	if _, err := c.AddFunc(
		fmt.Sprintf("0 %d %d * * *", config.Configs.Notice.Minute, config.Configs.Notice.Hour),
		Notice,
	); err != nil {
		log.Logger.Error("添加定时任务失败", zap.Error(err))
		return
	}
	c.Start()
	select {}
}
